﻿// ***********************************************************************
// Assembly         : MVC4Portal
// Author           : LJO+01 (Laurent Jordi)
// Created          : 06-05-2013
// Last Modified By : LJO+01 (Laurent Jordi)
// Last Modified On : 06-05-2013
// ***********************************************************************
// <copyright file="MyProfileController.cs" company="Copyright © Innovacall 2011">
//     Copyright (c) Copyright © Innovacall 2011. All rights reserved.
// </copyright>
// <summary></summary>
// ***********************************************************************
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Transactions;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using EmitMapper;
using InnovaApp.Layers.CommonLayer;
using InnovaApp.Layers.DataLayer;
using InnovaApp.Layers.DomainLayer;
using InnovaApp.Layers.ResourcesLayer.Properties;
using InnovaApp.Layers.SecurityLayer.Models.MetaModels;
using InnovaApp.Portals.MVC4Portal.Models.JSonModels;
using InnovaApp.Portals.MVC4Portal.Models.MetaModels.ContactManagement;
using InnovaApp.Portals.MVC4Portal.Models.ViewModels;
using InnovaApp.Portals.MVC4Portal.Models.ViewModels.LayoutViewModels;
using INNOVACALL.Framework.Common;
using INNOVACALL.Framework.Common.Extensions;
using INNOVACALL.Framework.Common.InnovacallExceptions;
using INNOVACALL.Framework.Common.MVCHelpers;
using INNOVACALL.Framework.Common.MVCHelpers.Localization;
using System.Drawing;
using System.Drawing.Imaging;
using InnovaApp.Portals.MVC4Portal.Filters;
using INNOVACALL.Framework.Common.Models;

namespace InnovaApp.Portals.MVC4Portal.Controllers.ViewControllers
{
    /// <summary>
    /// Class MyProfileController
    /// </summary>
    public partial class MyProfileController
    {
        /// <summary>
        /// Gets the profile detail Address.
        /// </summary>
        /// <param name="language">The language.</param>
        /// <param name="ajaxModel">The ajax model.</param>
        /// <returns>JsonResult.</returns>
        [HttpPost, Authorize, CacheManager(enCacheMode.NoCache)]
        public JsonResult ProfileDetailAddressGet(string language, ProfileDetailFeed_JSonModel ajaxModel)
        {
            string eMethod = eMethodBase + "ProfileDetailAddressGet[Post]";
            string scriptToExecute = string.Empty;
            object eParameters = new { language = language, ajaxModel = ajaxModel };
            JsonResult toReturn = new JsonResult { JsonRequestBehavior = JsonRequestBehavior.AllowGet };
            Contact_ContactAddress_MetaModel modelToFeed;
            INNOVACALL.Framework.Common.MVCHelpers.Localization.CommonLocalization.SetCurrentThreadLanguage(language);
            try
            {
                using (DataRepositories _dataContext = new DataRepositories())
                {
                    Contact dbContact = _dataContext.Contact_Rep.Query(x => x.FK_InnoAppUser == ajaxModel.UserId).FirstOrDefault();
                    if (ajaxModel.ItemToFeedId == -1)
                    {
                        modelToFeed = new Contact_ContactAddress_MetaModel();
                        if (dbContact == null)
                        {
                            throw new INNOVACALL.Framework.Common.InnovacallExceptions.DataIntegrityException(eMethod, eParameters, Resources.ErrMsg_NotFound);
                        }
                        modelToFeed.Id = -1;
                        modelToFeed.FK_Contact = dbContact.Id;
                        modelToFeed.IsDeliveryAddress = false;
                        modelToFeed.IsInvoicingAddress = false;
                        modelToFeed.IsPostAddress = false;
                    }
                    else
                    {
                        Contact_ContactAddress dbContact_Address = _dataContext.Contact_ContactAddress_Rep.Query(x => x.Id == ajaxModel.ItemToFeedId).FirstOrDefault();
                        if (dbContact_Address == null)
                        {
                            throw new INNOVACALL.Framework.Common.InnovacallExceptions.DataIntegrityException(eMethod, eParameters, Resources.ErrMsg_NotFound);
                        }
                        modelToFeed = ObjectMapperManager.DefaultInstance.GetMapper<Contact_ContactAddress, Contact_ContactAddress_MetaModel>().Map(dbContact_Address);
                        modelToFeed.IsDeliveryAddress = _dataContext.Contact_ContactAddress_AddressType_Rep.Query(x => x.FK_Contact_ContactAddress == dbContact_Address.Id && x.AddressType.isDelivery.Value).Count() > 0;
                        modelToFeed.IsInvoicingAddress = _dataContext.Contact_ContactAddress_AddressType_Rep.Query(x => x.FK_Contact_ContactAddress == dbContact_Address.Id && x.AddressType.isBilling.Value).Count() > 0;
                        modelToFeed.IsPostAddress = _dataContext.Contact_ContactAddress_AddressType_Rep.Query(x => x.FK_Contact_ContactAddress == dbContact_Address.Id && x.AddressType.isCorrespondence.Value).Count() > 0;
                    }
                }

                string htmlContent = base.RenderPartialViewToString("_ProfileDetailAddress", modelToFeed);
                toReturn.Data = new INNOVACALLAjaxResponse(
                    success: true,
                    domElementToUpdate: ajaxModel.HtmlElementToUpdate,
                    htmlContent: htmlContent,
                    scriptToExecute: null,
                    messageTitle: null,
                    message: null,
                    additionalData: new { @modelToFeed = modelToFeed, @forUserId = ajaxModel.UserId }
                );
            }
            catch (Exception ex)
            {
                INNOVACALL.Framework.Common.InnovacallExceptions.CommonException iex = new INNOVACALL.Framework.Common.InnovacallExceptions.CommonException(eMethod, eParameters, ex.Message);
                iex.LogIt();
                toReturn.Data = new INNOVACALLAjaxResponse(
                    success: false,
                    domElementToUpdate: null,
                    htmlContent: null,
                    scriptToExecute: "$.fn.jqDialogAlert(a.messageTitle ,a.message,'');",
                    messageTitle: Resources.View_All_DialogErrorTitle,
                    message: ex.LayoutException(),
                    additionalData: null
                );
            }
            return toReturn;
        }
        /// <summary>
        /// Profiles the detail Address add edit.
        /// Uses standard MVC Ajax system result in MainAjaxSuccess
        /// </summary>
        /// <param name="language">The language.</param>
        /// <param name="model">The model.</param>
        /// <returns>JsonResult.</returns>
        [HttpPost, Authorize, CacheManager(enCacheMode.NoCache)]
        public JsonResult ProfileDetailAddressAddEdit(string language, Contact_ContactAddress_MetaModel model)
        {
            string eMethod = eMethodBase + "ProfileDetailAddressAddEdit[Post]";
            string scriptToExecute = string.Empty;
            object eParameters = new { language = language, model = model };
            JsonResult toReturn = new JsonResult { JsonRequestBehavior = JsonRequestBehavior.AllowGet };
            INNOVACALL.Framework.Common.MVCHelpers.Localization.CommonLocalization.SetCurrentThreadLanguage(language);
            ContactAddress dbContactAddress;
            Contact_ContactAddress dbContact_ContactAddress;
            Contact_ContactAddress_AddressType dbContact_ContactAddress_AddressType;
            Guid userId;
            int Contact_AddressId;
            using (TransactionScope _ts = new TransactionScope())
            {

                try
                {
                    using (DataRepositories _dataContext = new DataRepositories())
                    {
                        Contact dbContact = _dataContext.Contact_Rep.GetById(model.FK_Contact);
                        if (dbContact == null)
                        {
                            throw new INNOVACALL.Framework.Common.InnovacallExceptions.DataIntegrityException(eMethod, eParameters, "Contact not found with the provided user key");
                        }
                        if (model.Id == -1)
                        {
                            //Address creation
                            dbContactAddress = ObjectMapperManager.DefaultInstance.GetMapper<ContactAddress_MetaModel, ContactAddress>().Map(model.ContactAddress);
                            _dataContext.ContactAddress_Rep.Add(dbContactAddress);
                            _dataContext.Save();
                            //ContactAddress creation
                            dbContact_ContactAddress = new Contact_ContactAddress()
                            {
                                FK_Contact = model.FK_Contact,
                                FK_ContactAddress = dbContactAddress.Id,
                                AddressLabel = model.AddressLabel,
                                SortIndex = _dataContext.Contact_ContactAddress_Rep.Query(x => x.FK_Contact == dbContact.Id).Count() + 1
                            };
                            _dataContext.Contact_ContactAddress_Rep.Add(dbContact_ContactAddress);
                            _dataContext.Save();
                            //AddressTypes joins creation
                            if (model.IsDeliveryAddress)
                            {
                                AddAddressType(_dataContext, enAddressTypes.Delivery, dbContact_ContactAddress.Id);
                            }
                            if (model.IsInvoicingAddress)
                            {
                                AddAddressType(_dataContext, enAddressTypes.Invoicing, dbContact_ContactAddress.Id);
                            }
                            if (model.IsPostAddress)
                            {
                                AddAddressType(_dataContext, enAddressTypes.Post, dbContact_ContactAddress.Id);
                            }
                            scriptToExecute = @"$.fn.ProfileDetailAddressUpdate(true,a.domElementToUpdate);";
                        }
                        else
                        {
                            dbContact_ContactAddress = _dataContext.Contact_ContactAddress_Rep.GetById(model.Id);
                            dbContact_ContactAddress.AddressLabel = model.AddressLabel;
                            UpdateAddressType(_dataContext, enAddressTypes.Delivery, dbContact_ContactAddress.Id, model.IsDeliveryAddress);
                            UpdateAddressType(_dataContext, enAddressTypes.Invoicing, dbContact_ContactAddress.Id, model.IsInvoicingAddress);
                            UpdateAddressType(_dataContext, enAddressTypes.Post, dbContact_ContactAddress.Id, model.IsPostAddress);
                            scriptToExecute = @"$.fn.ProfileDetailAddressUpdate(true,a.domElementToUpdate);";
                        }
                        _dataContext.Save();
                        Contact_AddressId = dbContact_ContactAddress.Id;
                        userId = _dataContext.Contact_Rep.GetById(dbContact_ContactAddress.FK_Contact).FK_InnoAppUser;
                        toReturn.Data = new INNOVACALLAjaxResponse(
                            success: true,
                            domElementToUpdate: model.DialogToClose,
                            htmlContent: null,
                            scriptToExecute: scriptToExecute,
                            messageTitle: null,
                            message: null,
                            additionalData: new { @forUserId = userId }
                        );
                    }
                    _ts.Complete();
                }
                catch (Exception ex)
                {
                    _ts.Dispose();
                    INNOVACALL.Framework.Common.InnovacallExceptions.CommonException iex = new INNOVACALL.Framework.Common.InnovacallExceptions.CommonException(eMethod, eParameters, ex.Message);
                    iex.LogIt();
                    toReturn.Data = new INNOVACALLAjaxResponse(
                        success: false,
                        domElementToUpdate: null,
                        htmlContent: null,
                        scriptToExecute: "$.fn.jqDialogAlert(a.messageTitle ,a.message,'');",
                        messageTitle: Resources.View_All_DialogErrorTitle,
                        message: ex.LayoutException(),
                        additionalData: null
                    );
                }
            }
            return toReturn;
        }

        /// <summary>
        /// Adds the type of the address.
        /// </summary>
        /// <param name="_dataContext">The _data context.</param>
        /// <param name="addressType">Type of the address.</param>
        /// <param name="contactAddressId">The contact address identifier.</param>
        private void AddAddressType(DataRepositories _dataContext, enAddressTypes addressType, int contactAddressId)
        {
            var dbContact_ContactAddress_AddressType = new Contact_ContactAddress_AddressType()
            {
                FK_Contact_ContactAddress = contactAddressId,
                FK_AddressType = EnumTools.EnumTypeTo<int>(addressType)
            };
            _dataContext.Contact_ContactAddress_AddressType_Rep.Add(dbContact_ContactAddress_AddressType);
            _dataContext.Save();
        }

        /// <summary>
        /// Updates the type of the address.
        /// </summary>
        /// <param name="_dataContext">The _data context.</param>
        /// <param name="addressType">Type of the address.</param>
        /// <param name="contactAddressId">The contact address unique identifier.</param>
        /// <param name="isAddressType">if set to <c>true</c> [is address type].</param>
        private void UpdateAddressType(DataRepositories _dataContext, enAddressTypes addressType, int contactAddressId, bool isAddressType)
        {
            Contact_ContactAddress_AddressType addressTypeJoin;
            int addressTypeId = EnumTools.EnumTypeTo<int>(addressType);
            var join = _dataContext.Contact_ContactAddress_AddressType_Rep.Query(x => x.FK_Contact_ContactAddress == contactAddressId && x.FK_AddressType == addressTypeId).FirstOrDefault();
            if (isAddressType)
            {
                if (join == null)
                {
                    addressTypeJoin = new Contact_ContactAddress_AddressType()
                    {
                        FK_Contact_ContactAddress = contactAddressId,
                        FK_AddressType = addressTypeId
                    };
                    _dataContext.Contact_ContactAddress_AddressType_Rep.Add(addressTypeJoin);
                    _dataContext.Save();
                }
            }
            else
            {
                if (join != null)
                {
                    _dataContext.Contact_ContactAddress_AddressType_Rep.Remove(join);
                    _dataContext.Save();
                }
            }
        }
        /// <summary>
        /// Profiles the detail address delete.
        /// </summary>
        /// <param name="language">The language.</param>
        /// <param name="ajaxModel">The ajax model.</param>
        /// <returns>JsonResult.</returns>
        /// <exception cref="INNOVACALL.Framework.Common.InnovacallExceptions.DataIntegrityException"></exception>
        [HttpPost, Authorize, CacheManager(enCacheMode.NoCache)]
        public JsonResult ProfileDetailAddressDelete(string language, ProfileDetailFeed_JSonModel ajaxModel)
        {
            string eMethod = eMethodBase + "ProfileDetailAddressAddEdit[Post]";
            string scriptToExecute = string.Empty;
            object eParameters = new { language = language, ajaxModel = ajaxModel };
            JsonResult toReturn = new JsonResult { JsonRequestBehavior = JsonRequestBehavior.AllowGet };
            INNOVACALL.Framework.Common.MVCHelpers.Localization.CommonLocalization.SetCurrentThreadLanguage(language);
            Contact_ContactAddress dbContact_ContactAddress;
            Contact_ContactAddress dbContact_ContactAddress_ToRenum;
            Guid userId;
            int removedSortIndex;
            int currentSortIndex;
            using (TransactionScope _ts = new TransactionScope())
            {
                try
                {
                    using (DataRepositories _dataContext = new DataRepositories())
                    {
                        dbContact_ContactAddress = _dataContext.Contact_ContactAddress_Rep.Query(x => x.Contact.FK_InnoAppUser == ajaxModel.UserId && x.Id == ajaxModel.ItemToFeedId).FirstOrDefault();
                        if (dbContact_ContactAddress == null)
                        {
                            throw new INNOVACALL.Framework.Common.InnovacallExceptions.DataIntegrityException(eMethod, eParameters, Resources.ErrMsg_NotFound);
                        }
                        userId = dbContact_ContactAddress.Contact.FK_InnoAppUser;
                        removedSortIndex = dbContact_ContactAddress.SortIndex;
                        _dataContext.Contact_ContactAddress_Rep.Remove(dbContact_ContactAddress);
                        _dataContext.Save();
                        //Renum Sort indexes
                        currentSortIndex = removedSortIndex;
                        IEnumerable<int> itemsToRenum = _dataContext.Contact_ContactAddress_Rep.Query(x => x.FK_Contact == dbContact_ContactAddress.FK_Contact && x.SortIndex >= removedSortIndex).OrderBy(x => x.SortIndex).Select(x => x.Id).AsEnumerable();
                        foreach (var id in itemsToRenum)
                        {
                            dbContact_ContactAddress_ToRenum = _dataContext.Contact_ContactAddress_Rep.GetById(id);
                            dbContact_ContactAddress_ToRenum.SortIndex = currentSortIndex;
                            _dataContext.Save();
                            currentSortIndex++;
                        }
                        _ts.Complete();

                        toReturn.Data = new INNOVACALLAjaxResponse(
                            success: true,
                            domElementToUpdate: ajaxModel.HtmlElementToUpdate,
                            htmlContent: string.Empty,
                            scriptToExecute: @"$.fn.ProfileDetailAddressUpdate(true,a.domElementToUpdate);",
                            messageTitle: null,
                            message: null,
                            additionalData: new { @forUserId = userId }
                        );
                    }
                }
                catch (Exception ex)
                {
                    _ts.Dispose();
                    INNOVACALL.Framework.Common.InnovacallExceptions.CommonException iex = new INNOVACALL.Framework.Common.InnovacallExceptions.CommonException(eMethod, eParameters, ex.Message);
                    iex.LogIt();
                    toReturn.Data = new INNOVACALLAjaxResponse(
                        success: false,
                        domElementToUpdate: ajaxModel.HtmlElementToUpdate,
                        htmlContent: null,
                        scriptToExecute: "$.fn.jqDialogAlert(a.messageTitle ,a.message,'');",
                        messageTitle: Resources.View_All_DialogErrorTitle,
                        message: ex.LayoutException(),
                        additionalData: null
                    );
                }
            }
            return toReturn;
        }
        /// <summary>
        /// Profiles the detail address move.
        /// </summary>
        /// <param name="language">The language.</param>
        /// <param name="ajaxModel">The ajax model.</param>
        /// <returns>JsonResult.</returns>
        /// <exception cref="INNOVACALL.Framework.Common.InnovacallExceptions.DataIntegrityException">
        /// Target to move not found
        /// or
        /// Target to move not found
        /// </exception>
        /// <exception cref="INNOVACALL.Framework.Common.InnovacallExceptions.CommonException">Direction parameter not correct</exception>
        [HttpPost, Authorize, CacheManager(enCacheMode.NoCache)]
        public JsonResult ProfileDetailAddressMove(string language, KendoGridElementMove_JSonModel ajaxModel)
        {
            string eMethod = eMethodBase + "ProfileDetailAddressMove[Post]";
            string scriptToExecute = string.Empty;
            object eParameters = new { language = language, ajaxModel = ajaxModel };
            JsonResult toReturn = new JsonResult { JsonRequestBehavior = JsonRequestBehavior.AllowGet };
            INNOVACALL.Framework.Common.MVCHelpers.Localization.CommonLocalization.SetCurrentThreadLanguage(language);
            Contact_ContactAddress dbContact_ContactAddressToMove = null;
            Contact_ContactAddress dbContact_ContactAddressTarget = null;
            using (TransactionScope _ts = new TransactionScope())
            {
                try
                {
                    using (DataRepositories _dataContext = new DataRepositories())
                    {
                        dbContact_ContactAddressToMove = _dataContext.Contact_ContactAddress_Rep.GetById(ajaxModel.id);
                        if (ajaxModel.direction == -1)
                        {
                            if (dbContact_ContactAddressToMove.SortIndex < 2)
                            {
                                //DoNothing
                                toReturn.Data = new INNOVACALLAjaxResponse(
                                    success: true,
                                    domElementToUpdate: null,
                                    htmlContent: string.Empty,
                                    scriptToExecute: null,
                                    messageTitle: null,
                                    message: null,
                                    additionalData: null
                                );
                            }
                            else
                            {
                                int dbContact_AddressToMoveSortIndex = dbContact_ContactAddressToMove.SortIndex;
                                int dbContact_AddressTargetSortIndex;
                                dbContact_ContactAddressTarget = _dataContext.Contact_ContactAddress_Rep.Query(x => x.FK_Contact == dbContact_ContactAddressToMove.FK_Contact && x.SortIndex == dbContact_ContactAddressToMove.SortIndex + ajaxModel.direction).FirstOrDefault();
                                if (dbContact_ContactAddressTarget == null)
                                {
                                    throw new INNOVACALL.Framework.Common.InnovacallExceptions.DataIntegrityException(eMethod, eParameters, "Target to move not found");
                                }
                                dbContact_AddressTargetSortIndex = dbContact_ContactAddressTarget.SortIndex;
                                dbContact_ContactAddressTarget.SortIndex = -1;
                                _dataContext.Save();
                                dbContact_ContactAddressToMove.SortIndex = dbContact_AddressTargetSortIndex;
                                _dataContext.Save();
                                dbContact_ContactAddressTarget.SortIndex = dbContact_AddressToMoveSortIndex;
                                _dataContext.Save();
                                _ts.Complete();
                                toReturn.Data = new INNOVACALLAjaxResponse(
                                    success: true,
                                    domElementToUpdate: null,
                                    htmlContent: null,
                                    scriptToExecute: ajaxModel.scriptToExecute,
                                    messageTitle: null,
                                    message: null,
                                    additionalData: null
                                );
                            }
                        }
                        else if (ajaxModel.direction == 1)
                        {
                            int count = _dataContext.Contact_ContactAddress_Rep.Query(x => x.FK_Contact == dbContact_ContactAddressToMove.FK_Contact).Count();
                            if (dbContact_ContactAddressToMove.SortIndex >= (count - 1))
                            {
                                //DoNothing
                                toReturn.Data = new INNOVACALLAjaxResponse(
                                    success: true,
                                    domElementToUpdate: null,
                                    htmlContent: string.Empty,
                                    scriptToExecute: null,
                                    messageTitle: null,
                                    message: null,
                                    additionalData: null
                                );
                            }
                            else
                            {
                                int dbContact_AddressToMoveSortIndex = dbContact_ContactAddressToMove.SortIndex;
                                int dbContact_AddressTargetSortIndex;
                                dbContact_ContactAddressTarget = _dataContext.Contact_ContactAddress_Rep.Query(x => x.FK_Contact == dbContact_ContactAddressToMove.FK_Contact && x.SortIndex == dbContact_ContactAddressToMove.SortIndex + ajaxModel.direction).FirstOrDefault();
                                if (dbContact_ContactAddressTarget == null)
                                {
                                    throw new INNOVACALL.Framework.Common.InnovacallExceptions.DataIntegrityException(eMethod, eParameters, "Target to move not found");
                                }
                                dbContact_AddressTargetSortIndex = dbContact_ContactAddressTarget.SortIndex;
                                dbContact_ContactAddressTarget.SortIndex = -1;
                                _dataContext.Save();
                                dbContact_ContactAddressToMove.SortIndex = dbContact_AddressTargetSortIndex;
                                _dataContext.Save();
                                dbContact_ContactAddressTarget.SortIndex = dbContact_AddressToMoveSortIndex;
                                _dataContext.Save();
                                _ts.Complete();
                                toReturn.Data = new INNOVACALLAjaxResponse(
                                    success: true,
                                    domElementToUpdate: null,
                                    htmlContent: null,
                                    scriptToExecute: ajaxModel.scriptToExecute,
                                    messageTitle: null,
                                    message: null,
                                    additionalData: null
                                );
                            }
                        }
                        else
                        {
                            throw new INNOVACALL.Framework.Common.InnovacallExceptions.CommonException(eMethod, eParameters, "Direction parameter not correct");
                        }
                    }
                }
                catch (Exception ex)
                {
                    _ts.Dispose();
                    INNOVACALL.Framework.Common.InnovacallExceptions.CommonException iex = new INNOVACALL.Framework.Common.InnovacallExceptions.CommonException(eMethod, eParameters, ex.Message);
                    iex.LogIt();
                    toReturn.Data = new INNOVACALLAjaxResponse(
                        success: false,
                        domElementToUpdate: null,
                        htmlContent: null,
                        scriptToExecute: "$.fn.jqDialogAlert(a.messageTitle ,a.message,'');",
                        messageTitle: Resources.View_All_DialogErrorTitle,
                        message: ex.LayoutException(),
                        additionalData: null
                    );
                }
            }
            return toReturn;
        }
    }
}
